package com.ytjj.qmyx.mall.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.ytjj.common.api.CommonPage;
import com.ytjj.common.api.CommonResult;
import com.ytjj.common.constants.QueueConstants;
import com.ytjj.common.dto.mqdto.OrderRecordDto;
import com.ytjj.common.exception.ApiException;
import com.ytjj.common.service.RedisService;
import com.ytjj.common.utils.TokenUtil;
import com.ytjj.qmyx.mall.constants.IsPayConstant;
import com.ytjj.qmyx.mall.constants.RedisConstants;
import com.ytjj.qmyx.mall.enums.ActivityTypeEnums;
import com.ytjj.qmyx.mall.enums.BannerStatusEnums;
import com.ytjj.qmyx.mall.enums.GroupBuyFinalStatusEnums;
import com.ytjj.qmyx.mall.enums.UserBalanceSourceEnums;
import com.ytjj.qmyx.mall.mapper.*;
import com.ytjj.qmyx.mall.model.*;
import com.ytjj.qmyx.mall.model.dto.AppNewLifeHallIndexGroupProductDto;
import com.ytjj.qmyx.mall.model.response.groupbuy.*;
import com.ytjj.qmyx.mall.model.response.groupbuy.ProcessGroupBuyListResponse;
import com.ytjj.qmyx.mall.service.*;
import com.ytjj.qmyx.mall.utils.TranslateTimeUtil;
import com.ytjj.qmyx.users.client.AdminClient;
import com.ytjj.qmyx.users.client.UsersClient;
import com.ytjj.qmyx.users.model.UserBalanceDto;
import lombok.extern.slf4j.Slf4j;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.temporal.ChronoUnit;
import java.util.*;
import java.util.concurrent.Executor;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

@Service
@Slf4j
@RefreshScope
public class GroupActivityServiceImpl implements GroupActivityService {
    @Resource
    private ProductMapper productMapper;
    @Resource
    private BannersMapper bannersMapper;
    @Autowired
    private YxProductGroupBuyInfoService yxProductGroupBuyInfoService;
    @Autowired
    private YxGroupBuyInfoService yxGroupBuyInfoService;
    @Autowired
    private YxGroupBuyUserRelService yxGroupBuyUserRelService;
    @Autowired
    private OrdersService ordersService;
    @Resource
    private OrdersInfoMapper ordersInfoMapper;
    @Autowired
    private UsersClient usersClient;
    @Autowired
    private RedisService redisService;
    @Resource
    private ProductDao productDao;
    @Resource
    public ProductGroupBuyInfoMapper productGroupBuyInfoMapper;
    @Resource
    private GroupBuyUserRelMapper groupBuyUserRelMapper;
    @Resource
    private GroupBuyInfoMapper groupBuyInfoMapper;
    @Resource
    private AdminClient adminClient;
    @Resource
    private OrdersSendRecordMapper ordersSendRecordMapper;
    @Autowired
    private RabbitTemplate rabbitTemplate;
    Executor pools = new ThreadPoolExecutor(5, 10, 5,
            TimeUnit.SECONDS, new LinkedBlockingQueue<>(1024 * 1024));

    @Value("${group.groupNum:3}")
    private Integer groupNum;
    @Value("${group.sucRatio:99}")
    private String sucRatio;
    @Value("${group.recommendNum:4}")
    private Integer recommendNum;

    /**
     * 精选拼团列表
     * @param pageSize
     * @param pageNum
     * @param activityType
     * @return
     */
    @Override
    public CommonResult<List<ProductByGroupActivityResponse>> getGroupWorkAll(Integer pageSize, Integer pageNum, String activityType, Integer userId) {
        PageHelper.startPage(pageNum, pageSize);
        log.info("===getGroupWorkAll==={}", TokenUtil.getPlatformData());
        List<Product> products = productMapper.queryProductListByGroup(ActivityTypeEnums.GROUP_WORK.name(), TokenUtil.getPlatformData(), userId);
        log.info("===products.size()==={}", products.size());
        List<String> headImgs = getHeadImgs();

        Random random = new Random();
        List<ProductByGroupActivityResponse> results = products.stream()
                .map(ProductByGroupActivityResponse::new)
                .collect(Collectors.toList());
        List<String> finalHeadImgs = headImgs;
        log.info("===results.size()==={}", results.size());
        results.stream().forEach(item -> {
            Collections.shuffle(finalHeadImgs);
            int randomVal = random.nextInt(finalHeadImgs.size() - 2);
            item.setHeadImgs(finalHeadImgs.subList(randomVal, randomVal + 2));
            log.info("===item.getDivideWay==={}", item.getDivideWay());
            if (item.getDivideWay().equals(2)) {
                item.setBalance(item.getFixedPrice());
            } else {
                item.setBalance(calculationBalance(item.getRatio(), item.getCurPrice(), item.getCostPrice(), item.getMinPerson()));
            }
        });
        return CommonResult.success(results);
    }

    /**
     * 快速参团列表
     * @param pageSize
     * @param pageNum
     * @param activityType
     * @return
     */
    @Override
    public CommonResult<List<ProductByGroupActivityResponse>> getQuickGroupWorkAll(Integer pageSize, Integer pageNum, String activityType, Integer userId) {
        Random random = new Random();
        PageHelper.startPage(pageNum, pageSize);
        List<Product> products = productMapper.queryQuickGroupWorkAll(ActivityTypeEnums.GROUP_WORK.name(), TokenUtil.getPlatformData(), userId);
        List<String> headImgs = getHeadImgs();

        List<Product> productList = new ArrayList<>();
        List<Integer> myGroups = new ArrayList<>();
        if (null != userId) {
            myGroups = queryCurUserJoinGroupId(userId);
        }
        if (!CollectionUtils.isEmpty(myGroups)) {
            List<Integer> finalMyGroups = myGroups;
            products.stream().forEach(product -> {
                if (!finalMyGroups.contains(product.getGroupId())) {
                    productList.add(product);
                }
            });
        }else {
            productList.addAll(products);
        }


        List<ProductByGroupActivityResponse> results = productList.stream()
                .map(ProductByGroupActivityResponse::new)
                .collect(Collectors.toList());
        List<String> finalHeadImgs = headImgs;
        results.stream().forEach(s -> {
            s.setSurplusNum(s.getMinPerson() - s.getJoinGroupPersonNum());
            s.setEndTimeSeconds((s.getEndTime().getTime() - System.currentTimeMillis()) / 1000L);
            Collections.shuffle(finalHeadImgs);
            int randomVal = random.nextInt(finalHeadImgs.size() - 2);
            s.setHeadImgs(finalHeadImgs.subList(randomVal, randomVal + 2));
            if (s.getDivideWay().equals(2)) {
                s.setBalance(s.getFixedPrice());
            } else {
                s.setBalance(calculationBalance(s.getRatio(), s.getCurPrice(), s.getCostPrice(), s.getMinPerson()));
            }
        });
        return CommonResult.success(results);
    }

    private BigDecimal calculationBalance(String ratio, BigDecimal groupPrice, BigDecimal costPrice, Integer minPerson) {
        BigDecimal grossProfit = groupPrice.subtract(costPrice);
//        BigDecimal balance = grossProfit.multiply(BigDecimal.valueOf(Long.valueOf(ratio))).
//                divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP).divide(new BigDecimal(minPerson - 1), 2, BigDecimal.ROUND_HALF_UP);
        BigDecimal balance = grossProfit.multiply(BigDecimal.valueOf(Long.valueOf(ratio))).divide(new BigDecimal(100), 0, BigDecimal.ROUND_HALF_UP);
        return balance.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : balance;
    }

    private List<Integer> queryCurUserJoinGroupId(Integer userId) {
        List<GroupBuyUserRel> groupBuyUserRelList = yxGroupBuyUserRelService.queryCurUserJoinGroupId(userId);
        return groupBuyUserRelList.stream().map(GroupBuyUserRel::getGroupId).collect(Collectors.toList());
    }

    /**
     * 得到虚拟用户头像集合
     * @return
     */
    private List<String> getHeadImgs() {
        List<String> headImgs = new LinkedList<>();
        Set<Object> imgsByRedis = redisService.sGet("zombie:headimgs");
        if (!imgsByRedis.isEmpty()) {
            Iterator iterator = imgsByRedis.iterator();
            while (iterator.hasNext()) {
                String dynamicStr = (String) iterator.next();
                headImgs.add(dynamicStr);
            }
        } else {
            headImgs = usersClient.queryZombieList();
            headImgs.stream().forEach(item -> {
                redisService.sSet("zombie:headimgs", item);
            });
            redisService.expire("zombie:headimgs", 10 * 24 * 60 * 60);
        }
        return headImgs;
    }

    /**
     * 我的拼团列表
     * @param pageSize
     * @param pageNum
     * @param activityType
     * @param status 0-拼团中 1-已完成 2-未拼中 3-全部
     * @return
     */
    @Override
    public CommonResult getMyGroupList(Integer pageSize, Integer pageNum, String activityType, Integer status, Integer userId) {
        PageHelper.startPage(pageNum, pageSize);
        List<Product> products = productMapper.queryMyGroupList(userId, status);
        List<ProductByGroupActivityResponse> results = products.stream()
                .map(ProductByGroupActivityResponse::new)
                .collect(Collectors.toList());
        results.stream().forEach(s -> {
            log.info("===s==={}", s);
            int joinGroupPersonNum = yxGroupBuyUserRelService.queryByGroupId(s.getGroupId()).size();
            s.setSurplusTime(TranslateTimeUtil.translateTime(s.getEndTime(), new Date()));
            s.setEndTimeSeconds((s.getEndTime().getTime() - System.currentTimeMillis()) / 1000L);
            s.setSurplusNum((null == s.getMinPerson() ? 0 : s.getMinPerson()) - joinGroupPersonNum);
            s.setFreight(BigDecimal.ZERO);
        });
        return CommonResult.success(results);
    }

    @Override
    public Integer getMyGroupNum(Integer userId) {
        Integer num = productMapper.queryMyGroupNum(userId);
        return num;
    }

    /**
     * 商品列表头部banners
     * @param activityType
     * @return
     */
    @Override
    public CommonResult queryBannersByActivity(String activityType) {
        BannersExample bannersExample = new BannersExample();
        bannersExample.createCriteria()
                .andTypeEqualTo(activityType)
                .andStatusEqualTo(BannerStatusEnums.SHOW.getValue());
        List<Banners> banners = bannersMapper.selectByExample(bannersExample);
        return CommonResult.success(banners);
    }

    /**
     * 查看商品详情
     * @param productId
     * @return
     */
    @Override
    public CommonResult queryDetail(Integer productId, Integer userId) {
        GroupBuyProductDetailResponse response = GroupBuyProductDetailResponse.builder()
                .productId(productId)
                .build();
        //待查询商品详情信息
        return CommonResult.success(queryGroupBuyInfo(response, userId));
    }

    /**
     * 查询拼团的一些数据
     * @param response
     * @return
     */
    private GroupBuyProductDetailResponse queryGroupBuyInfo(GroupBuyProductDetailResponse response, Integer userId) {
        Integer productId = response.getProductId();//商品id
        //根据商品id查询对应的拼团活动信息
        ProductGroupBuyInfo productGroupBuyInfo = yxProductGroupBuyInfoService.queryByProductId(productId);//拼团配置信息表
        if (null == productGroupBuyInfo) {
            throw new ApiException("找不到团参数信息");
        }

        response.setGroupPrice(productGroupBuyInfo.getGroupPrice());//拼团价
        response.setMinPerson(productGroupBuyInfo.getMinPerson());//几人成团

        //查询成团的条数
        long finalGroupBuyNum = yxGroupBuyInfoService.queryFinalGroupNumByProductId(productId);
        response.setFinalGroupBuyNum(finalGroupBuyNum);//已拼多少件
        //查询正在拼团人数
        Integer processGroupBuyNum = yxGroupBuyInfoService.queryProcessGroupBuyNumByProductId(productId);
        response.setProcessGroupBuyNum(processGroupBuyNum);//多少人正在拼团
        //查询正在拼团列表
        List<ProcessGroupBuyListResponse> processGroupBuyList = yxGroupBuyInfoService.queryProcessGroupBuyList(productId);
        List<ProcessGroupBuyListResponse> myDonotGroups = new ArrayList<>();
        //查询当前用户参与的团
        if (null != userId) {
            List<GroupBuyUserRel> rels = yxGroupBuyUserRelService.queryCurUserJoinGroupId(userId);
            if (!CollectionUtils.isEmpty(rels)) {
                List<Integer> myGroupIds = rels.stream().map(GroupBuyUserRel::getGroupId).collect(Collectors.toList());
                processGroupBuyList.stream().forEach(group -> {
                    if (!myGroupIds.contains(group.getGroupId())) {
                        myDonotGroups.add(group);
                    }
                });
            }else {
                myDonotGroups.addAll(processGroupBuyList);
            }
        }else {
            myDonotGroups.addAll(processGroupBuyList);
        }
        response.setProcessGroupBuyList(myDonotGroups);//正在拼团列表

        //猜你喜欢商品
        Product product = productDao.getProductById(productId);
        response.setRecommend(productDao.getRecommendByGroup(product.getCategoryId()));
        if (productGroupBuyInfo.getDivideWay().equals(1)) {
            response.setBalance(calculationBalance(productGroupBuyInfo.getRatio(), productGroupBuyInfo.getGroupPrice(), product.getCostPrice(), productGroupBuyInfo.getMinPerson()));
        } else {
            response.setBalance(productGroupBuyInfo.getFixedPrice());//.divide(new BigDecimal(productGroupBuyInfo.getMinPerson() - 1), 2, BigDecimal.ROUND_HALF_UP)
        }
        return response;
    }


    /**
     * 支付完成后更新yx_group_buy_user_rel表状态
     * @return
     */
    @Override
    @Transactional
    public boolean updateGoupBuyUserRelStatus(String orderNo, Integer status) {
        log.info("===更新拼团成员数据开始==={},{}", orderNo, status);
        GroupBuyUserRel groupBuyUserRel = yxGroupBuyUserRelService.getByOrderNo(orderNo);
        if (null == groupBuyUserRel) {
            log.info("===没有需要更新的拼团成员数据==={}", orderNo);
            return true;
        }
        log.info("===groupBuyUserRel==={}", groupBuyUserRel);
        if (groupBuyUserRel.getStatus() == 1) {
            log.info("===状态不需要更新了==={}", orderNo);
            return true;
        }
        groupBuyUserRel.setStatus(status);
        boolean result = yxGroupBuyUserRelService.update(groupBuyUserRel);
        if (!result) {
            log.error("===更新拼团成员数据失败==={}", orderNo);
            return false;
        }
        //如果是团主，则需要开团
        if (groupBuyUserRel.getGroupRole() == 1) {
            Orders orders = ordersService.getByOrderNo(orderNo);
            OrdersInfo ordersInfo = null;//ordersInfoMapper.selectByPrimaryKey(orders.getId())
            List<OrdersInfo> ordersInfos = ordersInfoMapper.selectOrderInfoByOrderId(orders.getId());
            if (!CollectionUtils.isEmpty(ordersInfos)) {
                ordersInfo = ordersInfos.get(0);
            }
            GroupBuyInfo groupBuyInfo = new GroupBuyInfo();
            groupBuyInfo.setUserId(groupBuyUserRel.getUserId());
            groupBuyInfo.setProductId(ordersInfo.getProductId());
            //根据productId查下正在参与的拼团参数信息
            ProductGroupBuyInfo productGroupBuyInfo = yxProductGroupBuyInfoService.queryByProductId(ordersInfo.getProductId());
            log.info("===productGroupBuyInfo==={},{}", productGroupBuyInfo, ordersInfo.getProductId());
            if (null != productGroupBuyInfo) {
                groupBuyInfo.setGroupId(productGroupBuyInfo.getId());
            }
            ZoneId zoneId = ZoneId.systemDefault();//获得时区
            LocalDateTime curDate = LocalDateTime.now();
            LocalDateTime processDay = curDate.plus(productGroupBuyInfo.getProcessDay(), ChronoUnit.DAYS);//时间加1天
            groupBuyInfo.setCreateTime(new Date());
            Date endTime = Date.from(processDay.atZone(zoneId).toInstant());
            groupBuyInfo.setEndTime(endTime);
            groupBuyInfo.setFinalResult(GroupBuyFinalStatusEnums.PROCESS.getCode().byteValue());
            groupBuyInfo.setUpdateTime(new Date());
            int insert_result = yxGroupBuyInfoService.insert(groupBuyInfo);

            //开团成功回写团成员表的group_id字段
            if (insert_result > 0) {
                groupBuyUserRel.setGroupId(groupBuyInfo.getId());
                yxGroupBuyUserRelService.update(groupBuyUserRel);
            }
        }else {
            GroupBuyInfo groupBuyInfo = yxGroupBuyInfoService.selectById(groupBuyUserRel.getGroupId());
            Integer minPerson = null;
            if (null == groupBuyInfo) {
                log.info("===团信息不存在==={}", groupBuyUserRel.getGroupId());
            }else {
                ProductGroupBuyInfo productGroupBuyInfo = productGroupBuyInfoMapper.selectByPrimaryKey(groupBuyInfo.getGroupId());
                if (null != productGroupBuyInfo) {
                    minPerson = productGroupBuyInfo.getMinPerson();
                }
            }
            if (null != groupBuyInfo && null != minPerson) {
                //当前团已参团真实用户信息
                GroupBuyUserRelExample groupBuyUserRelExample = new GroupBuyUserRelExample();
                groupBuyUserRelExample.createCriteria().andGroupIdEqualTo(groupBuyUserRel.getGroupId()).andStatusEqualTo(1).andOrderNoIsNotNull();
                List<GroupBuyUserRel> buyPersonNum = groupBuyUserRelMapper.selectByExample(groupBuyUserRelExample);
                log.info("===minPerson={},buyPersonNum={}", minPerson.intValue(), buyPersonNum.size());
                if (minPerson.intValue() <= buyPersonNum.size()) {
                    groupBuyInfo.setFinalResult((byte)1);
                    groupBuyInfoMapper.updateByPrimaryKeySelective(groupBuyInfo);

                    doHandle(buyPersonNum);
                }
            }
        }
        return true;
    }

    private void doHandle(List<GroupBuyUserRel> buyPersonNum) {
        Random random = new Random();
        //是否开启团主不参与中奖 1-参与 2-不参与
        Integer groupRoleMainFlag = Integer.parseInt(null == redisService.get("GROUP_MAIN_ROLE_FLAG") ? "2" : redisService.get("GROUP_MAIN_ROLE_FLAG"));
        GroupBuyUserRel winFlagObj = null;
        if (groupRoleMainFlag.equals(2)) {
            List<GroupBuyUserRel> mainGroupRoleExclude = buyPersonNum.stream().filter(userRel -> userRel.getGroupRole() != (byte)1).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(mainGroupRoleExclude) && mainGroupRoleExclude.size() == 1) {
                winFlagObj = mainGroupRoleExclude.get(0);
            }else {
                winFlagObj = mainGroupRoleExclude.get(random.nextInt(mainGroupRoleExclude.size()));
            }
        }else {
            winFlagObj = buyPersonNum.get(random.nextInt(buyPersonNum.size()));
        }
        winFlagObj.setWinFlag(1);
        groupBuyUserRelMapper.updateByPrimaryKeySelective(winFlagObj);
        refundOrdersByGroupBuy();
        try {
            //发送kafka
            doSendOrderRecordToKafka(winFlagObj.getOrderNo());
        } catch (Exception e) {
            log.info("===记录拼团成功订单失败==={}", winFlagObj.getOrderNo());
        }
    }

    /**
     * 发送订单记录
     * @param orderNo
     */
    private void doSendOrderRecordToKafka(String orderNo) {
        Orders order = ordersService.getByOrderNo(orderNo);
        if (null == order) {
            return;
        }
        List<OrdersInfo> ordersInfoList = ordersInfoMapper.selectOrderInfoByOrderId(order.getId());
        if (CollectionUtils.isEmpty(ordersInfoList)) {
            return;
        }
        ordersInfoList.stream().forEach(orderInfo -> {
            Product product = productMapper.selectByPrimaryKey(orderInfo.getProductId());

            OrderRecordDto orderRecordDto = new OrderRecordDto(order.getUserId()==null?"0":String.valueOf(order.getUserId()),order.getId(), orderInfo.getId(), order.getOrderNo(), product.getId(), product.getProductName(),
                    product.getCostPrice(), product.getOriginalPrice(), product.getPrice(), order.getOrderSource(), order.getChannel(),
                    orderInfo.getActivityType(), IsPayConstant.NO.intValue(), org.apache.commons.lang3.StringUtils.isEmpty(order.getUserAddress()) ? 0 : 1, order.getCreateTime(), order.getIsFirstBuy(),
                    order.getUserId(),order.getPayType(),order.getPaySource(),order.getCity(),order.getArea(),order.getAddress(),order.getProvince(),
                    order.getUserAddress(),null,new Date(), order.getDynamicId());

            OrdersSendRecordExample ordersSendRecordExample=new OrdersSendRecordExample();
            ordersSendRecordExample.setOrderByClause("id desc");
            ordersSendRecordExample.createCriteria().andOrderinfoIdEqualTo(orderInfo.getId())
                    .andTypeEqualTo((byte)1);
            List<OrdersSendRecord> sendRecordList=ordersSendRecordMapper.selectByExample(ordersSendRecordExample);
            if(CollectionUtils.isEmpty(sendRecordList)){
                OrdersSendRecord sendRecord = new OrdersSendRecord();
                sendRecord.setOrderinfoId(orderInfo.getId());
                sendRecord.setType((byte)1);
                sendRecord.setSucFlag((byte)1);
                sendRecord.setCreateTime(new Date());
                try {
                    rabbitTemplate.convertAndSend(QueueConstants.ORDER_RECORD_QUEUE,orderRecordDto);
                } catch (Exception e) {
                    log.error("===订单创建发送rabbitmq异常==={},{}", e, order);
                    sendRecord.setSucFlag((byte)0);
                }
                ordersSendRecordMapper.insert(sendRecord);
            }

            ordersSendRecordExample=new OrdersSendRecordExample();
            ordersSendRecordExample.setOrderByClause("id desc");
            ordersSendRecordExample.createCriteria().andOrderinfoIdEqualTo(orderInfo.getId())
                    .andTypeEqualTo((byte)2);
            sendRecordList = ordersSendRecordMapper.selectByExample(ordersSendRecordExample);
            if(CollectionUtils.isEmpty(sendRecordList)){
                OrdersSendRecord sendRecord = new OrdersSendRecord();
                sendRecord.setOrderinfoId(orderInfo.getId());
                sendRecord.setType((byte)2);
                sendRecord.setSucFlag((byte)1);
                sendRecord.setCreateTime(new Date());
                try {
                    rabbitTemplate.convertAndSend(QueueConstants.ORDER_RECORD_QUEUE, orderRecordDto);
                } catch (Exception e) {
                    log.error("===订单支付发送rabbitmq异常==={},{}", e, order);
                    sendRecord.setSucFlag((byte)0);
                }
                ordersSendRecordMapper.insert(sendRecord);
            }
        });
    }

    /**
     * 已成团未中奖的用户退款操作
     * @return
     */
    public boolean refundOrdersByGroupBuy() {
        //开团信息表
        GroupBuyInfoExample example = new GroupBuyInfoExample();
        example.createCriteria().andFinalResultEqualTo((byte)1);//.andEndTimeGreaterThan(new Date())
        List<GroupBuyInfo> groupInfos = groupBuyInfoMapper.selectByExample(example);
        groupInfos.stream().forEach(s -> {
            GroupBuyUserRelExample groupBuyUserRelExample = new GroupBuyUserRelExample();
            groupBuyUserRelExample.createCriteria().andStatusEqualTo(1)
                    .andVirtualUserEqualTo((byte)0)
                    .andWinFlagEqualTo(0)
                    .andRefundFlagEqualTo(0)
                    .andGroupIdEqualTo(s.getId())
                    .andOrderNoIsNotNull();
            List<GroupBuyUserRel> buyPersonNum = groupBuyUserRelMapper.selectByExample(groupBuyUserRelExample);
            buyPersonNum.stream().forEach(s2 -> {
                Integer orderId = ordersService.getByOrderNo(s2.getOrderNo()).getId();
                String result = adminClient.refundOrdersByRpc(orderId, "拼团未中奖用户退款");
                log.info("===result==={}, {}", result, orderId);
                if ("200".equals(result)) {
                    s2.setRefundFlag(1);
                    groupBuyUserRelMapper.updateByPrimaryKeySelective(s2);
                }
            });
        });
        return true;
    }

    /**
     * todo
     * 当实际参团人数达标后，主动更新团状态
     * @param orderNo
     * @return
     */
    private boolean handleRealBuyUserFull(String orderNo) {
        return true;
    }

    /**
     * 开团/参团成功后的订单详情中拼团一些属性
     * @param groupId
     * @return
     */
    @Override
    public GroupBuyOrderDetailResponse queryOrderDetailGroupPropertiesByOrderNo(Integer groupId, Integer productId, Integer userId, Integer orderId) {
        log.info("===queryOrderDetailGroupPropertiesByOrderNo==={},{},{},{}", groupId, productId, userId, orderId);
        if (null != orderId) {
            Orders orders = ordersService.getById(orderId);
            log.info("===orders==={}", orders.getOrderNo());
            GroupBuyUserRel userRel = yxGroupBuyUserRelService.getByOrderNo(orders.getOrderNo()); //团成员信息
            log.info("===userRel.getGroupId()==={}", userRel.getGroupId());
            GroupBuyInfo groupBuyInfo = yxGroupBuyInfoService.selectById(userRel.getGroupId());//开团信息
            if (null == groupBuyInfo) {
                try{
                    ordersService.updateGoupBuyUserRelStatus(orders.getOrderNo(), 1);
                    log.info("===更新团员成员表完成====");
                    userRel = yxGroupBuyUserRelService.getByOrderNo(orders.getOrderNo()); //团成员信息
                    groupBuyInfo = yxGroupBuyInfoService.selectById(userRel.getGroupId());//开团信息
                } catch (Exception e) {
                    log.info("===支付完成后更新yx_group_buy_user_rel表状态异常==={}", e);
                }
            }
            log.info("====groupBuyInfo==={}", groupBuyInfo);
            ProductGroupBuyInfo productGroupBuyInfo = yxProductGroupBuyInfoService.queryByProductId(groupBuyInfo.getProductId());//团配置信息
            List<GroupBuyUserRel> userRels = yxGroupBuyUserRelService.queryByGroupId(groupBuyInfo.getId());//团员列表
            List<Integer> userIds = userRels.stream().map(GroupBuyUserRel::getUserId).collect(Collectors.toList());//用来判断自己是否已购买
            List<GroupBuyUserRel> winUserIds = userRels.stream().filter(s -> s.getWinFlag()==1).collect(Collectors.toList());//中奖的团员
            GroupBuyOrderDetailResponse response = new GroupBuyOrderDetailResponse();

            Product product = productMapper.selectByPrimaryKey(productGroupBuyInfo.getProductId());
            response.setMinPerson(productGroupBuyInfo.getMinPerson());
            response.setTitle(product.getLongTitle());
            response.setWinPersonNum(1);
            response.setBackPersonNum(response.getMinPerson() - response.getWinPersonNum());
            response.setOriginalPrice(product.getOriginalPrice());
            response.setGroupPrice(productGroupBuyInfo.getGroupPrice());
            response.setEndTime(groupBuyInfo.getEndTime());
            response.setEndTimeSeconds((groupBuyInfo.getEndTime().getTime() - System.currentTimeMillis()) / 1000L);
            response.setGroupUserList(userRels);
            response.setSurplusPersonNum(response.getMinPerson() - userRels.size());
            response.setGroupNum(groupNum);
            response.setSucRatio(sucRatio);
            response.setBuyFlag(0);
            response.setFinalResult(groupBuyInfo.getFinalResult());
            response.setImgUrl(product.getProductImg());
            response.setOrderId(orderId);
            response.setProductId(productGroupBuyInfo.getProductId());
            response.setGroupId(groupId);
            for (GroupBuyUserRel rel : userRels) {
                if (rel.getWinFlag()==1){
                    response.setWinHeadImg(rel.getHeadImg());
                }
            }
            if (userIds.contains(userId)) {
                response.setBuyFlag(1);
            }
            response.setWinFlag(0);
            winUserIds.stream().forEach(s -> {
                if (s.getUserId().equals(userId)) {
                    response.setWinFlag(1);//是否中奖
                }
            });
            return response;
        }
        log.info("===groupId==={}", groupId);
        GroupBuyInfo groupBuyInfo = yxGroupBuyInfoService.selectById(groupId);//开团信息
        ProductGroupBuyInfo productGroupBuyInfo = yxProductGroupBuyInfoService.queryByProductId(groupBuyInfo.getProductId());//团配置信息
        List<GroupBuyUserRel> userRels = yxGroupBuyUserRelService.queryByGroupId(groupBuyInfo.getId());//团员列表
        List<Integer> userIds = userRels.stream().map(GroupBuyUserRel::getUserId).collect(Collectors.toList());//用来判断自己是否已购买
        List<GroupBuyUserRel> winUserIds = userRels.stream().filter(s -> s.getWinFlag()==1).collect(Collectors.toList());//中奖的团员
        GroupBuyOrderDetailResponse response = new GroupBuyOrderDetailResponse();

        Product product = productMapper.selectByPrimaryKey(productGroupBuyInfo.getProductId());
        response.setMinPerson(productGroupBuyInfo.getMinPerson());
        response.setTitle(product.getLongTitle());
        response.setWinPersonNum(1);
        response.setBackPersonNum(response.getMinPerson() - response.getWinPersonNum());
        response.setOriginalPrice(product.getOriginalPrice());
        response.setGroupPrice(productGroupBuyInfo.getGroupPrice());
        response.setEndTime(groupBuyInfo.getEndTime());
        response.setEndTimeSeconds((groupBuyInfo.getEndTime().getTime() - System.currentTimeMillis()) / 1000L);
        response.setGroupUserList(userRels);
        response.setSurplusPersonNum(response.getMinPerson() - userRels.size());
        response.setGroupNum(groupNum);
        response.setSucRatio(sucRatio);
        response.setBuyFlag(0);
        response.setFinalResult(groupBuyInfo.getFinalResult());
        response.setImgUrl(product.getProductImg());
        response.setProductId(productGroupBuyInfo.getProductId());
        response.setGroupId(groupId);
        String orderNo = "";
        for (GroupBuyUserRel rel : userRels) {
            if (rel.getWinFlag() == 1){
                response.setWinHeadImg(rel.getHeadImg());
                orderNo = rel.getOrderNo();
            }
        }
        Integer id = ordersService.selectByorderNo(orderNo);
        response.setOrderId(id);
        if (userIds.contains(userId)) {
            response.setBuyFlag(1);
        }
        response.setWinFlag(0);
        winUserIds.stream().forEach(s -> {
            if (s.getUserId().equals(userId)) {
                response.setWinFlag(1);//是否中奖
            }
        });

        return response;
    }

    /**
     * 精选拼团推荐
     * @return
     */
    @Override
    public CommonResult queryFineGroupList(Integer userId) {
        List<Product> list = productMapper.queryFineGroupList(TokenUtil.getPlatformData(), recommendNum);
        //查询当前用户参与的团
        List<Product> myDonotGroups = new ArrayList<>();
        if (null != userId) {
            List<GroupBuyUserRel> rels = yxGroupBuyUserRelService.queryCurUserJoinGroupId(userId);
            if (!CollectionUtils.isEmpty(rels)) {
                List<Integer> myGroupIds = rels.stream().map(GroupBuyUserRel::getGroupId).collect(Collectors.toList());
                list.stream().forEach(group -> {
                    if (!myGroupIds.contains(group.getGroupId())) {
                        myDonotGroups.add(group);
                    }
                });
            }else {
                myDonotGroups.addAll(list);
            }
        }else {
            myDonotGroups.addAll(list);
        }
        List<FineGroupRecommendListResponse> results = new ArrayList<>();
        list.stream().forEach(s -> {
            List<GroupBuyUserRel> userRels = yxGroupBuyUserRelService.queryByGroupId(s.getGroupId());//团员列表
            FineGroupRecommendListResponse response = FineGroupRecommendListResponse.builder()
                    .productId(s.getId())
                    .imgUrl(s.getProductImg())
                    .minPerson(s.getMinPerson())
                    .longTitle(s.getLongTitle())
                    .groupPrice(s.getCurPrice())
                    .originalPrice(s.getOriginalPrice())
                    .groupUserList(userRels)
                    .build();
            results.add(response);
        });
        return CommonResult.success(results);
    }

    /**
     * 团成功未中奖，领取红包
     * @param orderNo
     * @param userId
     * @return
     */
    @Override
    @Transactional
    public CommonResult receiveRedPack(String orderNo, Integer userId) {
        BigDecimal balance = BigDecimal.ZERO;
        GroupBuyUserRel userRel = yxGroupBuyUserRelService.getByOrderNoAndUserId(orderNo, userId); //团成员信息
        if (null == userRel || userRel.getStatus() == 0) {
            throw new ApiException("未找到对应的拼团订单信息");
        }
        if (userRel.getRedFlag() == 1) {
            throw new ApiException("您已领取过红包，不能重复领取");
        }
        Orders orders = ordersService.getByOrderNo(orderNo);
        GroupBuyInfo groupBuyInfo = yxGroupBuyInfoService.selectById(userRel.getGroupId());//开团信息
        if (null == groupBuyInfo || groupBuyInfo.getFinalResult() != 1) {
            throw new ApiException("未找到对应的团信息或团未成功");
        }
        if (userRel.getWinFlag() == 1) {
            throw new ApiException("您已中奖，不能继续领取红包");
        }
        ProductGroupBuyInfo productGroupBuyInfo = yxProductGroupBuyInfoService.queryByProductId(groupBuyInfo.getProductId());//团配置信息
        if (null != productGroupBuyInfo && productGroupBuyInfo.getDivideWay() == 2) {
            balance = productGroupBuyInfo.getFixedPrice().divide(new BigDecimal(productGroupBuyInfo.getMinPerson() - 1), 2, BigDecimal.ROUND_HALF_UP);
        } else {
            Product product = productMapper.selectByPrimaryKey(productGroupBuyInfo.getProductId());
            //计算能够领取的红包金额
            //毛利=售价-成本价=拼团售价 - costPrice
            BigDecimal grossProfit = productGroupBuyInfo.getGroupPrice().subtract(product.getCostPrice());
            if (grossProfit.compareTo(BigDecimal.ZERO) <= 0) {
                log.info("===毛利=0了===");
                return CommonResult.success(balance);
            }
            log.info("==balance==={},{},{}", grossProfit, productGroupBuyInfo.getRatio(), productGroupBuyInfo.getMinPerson());
            balance = grossProfit.multiply(BigDecimal.valueOf(Long.valueOf(productGroupBuyInfo.getRatio()))).divide(new BigDecimal(100), 2, BigDecimal.ROUND_HALF_UP).divide(new BigDecimal(productGroupBuyInfo.getMinPerson() - 1), 2, BigDecimal.ROUND_HALF_UP);
        }

        if (balance.compareTo(BigDecimal.ZERO) < 0) {
            log.info("===红包金额为负数了==={}", balance);
            balance = BigDecimal.ZERO;
        }

        log.info("===团成功未中奖，领取红包={}元===", balance);

        userRel.setRedFlag(1);
        userRel.setRedPackBalance(balance);
        yxGroupBuyUserRelService.update(userRel);
        try {
            //增加用户余额
            UserBalanceDto userBalanceDto = new UserBalanceDto();
            userBalanceDto.setUserId(userId);
            userBalanceDto.setUpdateMoney(balance);
            userBalanceDto.setType("ADD");
            userBalanceDto.setSource(UserBalanceSourceEnums.GROUP_BUY.name());
            userBalanceDto.setAmountType(1);
            userBalanceDto.setCode(String.valueOf(orders.getId()));
            usersClient.updateMoney(userBalanceDto);
        } catch (Exception e) {
            log.error("===拼团领红包增加用户余额失败==={},{}", userId, balance);
        }

        return CommonResult.success(balance);
    }

    /**
     * App生活馆拼团的商品信息
     * @return
     */
    @Override
    public List<AppNewLifeHallIndexGroupProductDto> queryFineGroupListByNewLifeHall(Integer pageNum, Integer pageSize) {
        List<AppNewLifeHallIndexGroupProductDto> results = new ArrayList<>();
        PageHelper.startPage(pageNum, pageSize);
        List<Product> list = productMapper.queryFineGroupListByPage("APP");
        if (!CollectionUtils.isEmpty(list)) {
            list.stream().forEach(item -> {
                AppNewLifeHallIndexGroupProductDto dto = new AppNewLifeHallIndexGroupProductDto();
                dto.setId(item.getId());
                dto.setProductImg(item.getProductImg());
//                dto.setPrice(item.getCurPrice());
                results.add(dto);
                redisService.sSet(RedisConstants.CUR_GROUP_DATAS, JSON.toJSONString(item));
            });
            redisService.set(RedisConstants.CUR_GROUP_DATAS_HAVEVALUE, "1");
            redisService.expire(RedisConstants.CUR_GROUP_DATAS_HAVEVALUE, 5 * 60);
        }

        CommonPage commonPage = CommonPage.restPage(results);
        redisService.set(RedisConstants.GROUP_PAGES, String.valueOf(commonPage.getTotalPage()));
        return results;
    }
}
